<?php

namespace App\Http\Controllers\Order;

use App\Helper\Functions;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use App\Http\Models\AgencyAddress;
use App\Http\Models\AgencyOrder;
use App\Http\Models\Knight;
use App\http\Models\KnightWork;
use App\http\Models\UserFree;
use Ixudra\Curl\Facades\Curl;
use Illuminate\Support\Facades\Log;

use App\Http\Controllers\Auth\IndexController as authIndex;

class IndexController extends Controller
{
    private $developerArray = ['o1URZ5GKaji3OdDnTodRbvn3qiK4'];

    // 获取下拉框列表
    public function getRangeList($rangeType, $parentId){

        if ($rangeType == 'city'){
            $cityList = DB::table('config_region')
                            ->where('crType', '2')
                            ->where('crEnable', 1)
                            ->pluck('crName');
            $idList = DB::table('config_region')
                            ->where('crType', '2')
                            ->where('crEnable', 1)
                            ->pluck('crId');
            $returnData = array();
            $returnData['nameList'] = $cityList;
            $returnData['idList'] = $idList;
            return $this->returnMsg(1, 'OK', $returnData);
        } else if ($rangeType == 'school'){
            $schoolList = DB::table('config_school')
                        ->where('crId', $parentId)
                        ->where('csEnable', 1)
                        ->pluck('csName');
            $idList = DB::table('config_school')
                        ->where('crId', $parentId)
                        ->where('csEnable', 1)
                        ->pluck('csId');
            $returnData = array();
            $returnData['nameList'] = $schoolList;
            $returnData['idList'] = $idList;
            return $this->returnMsg(1, 'OK', $returnData);
        } else if ($rangeType == 'site'){
            $siteList = DB::table('school_site')
                        ->where('csId', $parentId)
                        ->where('ssEnable', 1)
                        ->pluck('ssName');
            $idList = DB::table('school_site')
                        ->where('csId', $parentId)
                        ->where('ssEnable', 1)
                        ->pluck('ssId');
            $returnData = array();
            $returnData['nameList'] = $siteList;
            $returnData['idList'] = $idList;

            if (count($siteList) == 0){
                $returnData['nameList'] = array('自定义');
                $returnData['idList'] = array(0);
            }
            return $this->returnMsg(1, 'OK', $returnData);
        } else {
            $returnData = array();
            $returnData['nameList'] = [['成都'],['四川大学', '西南交通大学'],['南区1栋','南区2栋','南区3栋','南区4栋','南区5栋']];
            $returnData['idList'] = [[271],[1,2],[1,2,3,4,5]];
            return $this->returnMsg(1, 'OK', $returnData);
        }
    }

    // 添加收货地址
    public function addReceiveAddress(Request $request){

        $token = $request->token;

        $name = $request->name;
        $sex = $request->sex;
        $mobile = $request->mobile;
        $school = $request->school;
        $schoolId = $request->schoolId;
        $site = $request->site;
        $siteId = $request->siteId;
        $address = $request->address;
        $customAddress = $request->customAddress;

        $userInfo = $this->getUserInfoFromToken($token);

        $AgencyAddress = new AgencyAddress();
        $AgencyAddress->add($userInfo['uCode'], $name, $sex, $mobile, $schoolId, $school, $siteId, $site, $address, $customAddress);

        return $this->returnMsg(1, 'OK');
    }

    // 获取收货地址列表
    public function getReceiveAddressList($token, $orderType='express'){

        if ($orderType == 'takeOut'){
            $orderType = 'express';
        }
        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyAddress = new AgencyAddress();
        $list = $AgencyAddress->getList($userInfo['uCode'], $orderType);

        return $this->returnMsg(1, 'OK', $list);
    }

    // 获取默认收货地址
    public function getDefaultReceiveAddress($token){

        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyAddress = new AgencyAddress();
        $info = $AgencyAddress->getDefault($userInfo['uCode']);

        return $this->returnMsg(1, 'OK', $info);
    }

    // 获取收货地址信息
    public function getReceiveAddress($aaId, $token){

        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyAddress = new AgencyAddress();
        $info = $AgencyAddress->getInfo($aaId, $userInfo['uCode']);

        return $this->returnMsg(1, 'OK', $info);
    }

    // 删除收货地址信息
    public function delReceiveAddress(Request $request){

        $aaId = $request->aaId;
        $token = $request->token;

        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyAddress = new AgencyAddress();
        $AgencyAddress->delAddress($aaId, $userInfo['uCode']);

        return $this->returnMsg(1, 'OK');
    }

    // 获取取货地址列表
    public function getTakeAddressList($csId){
        $listName = DB::table('school_take')
                    ->select(DB::raw("CONCAT(csName,' ', stName) AS site "))
                    ->leftJoin('config_school', 'school_take.csId', '=', 'config_school.csId')
                    ->where('school_take.csId', $csId)
                    ->pluck('site');
        $listId = DB::table('school_take')
                    ->leftJoin('config_school', 'school_take.csId', '=', 'config_school.csId')
                    ->where('school_take.csId', $csId)
                    ->pluck('stId');
        $returnData = array();
        $returnData['nameList'] = $listName;
        $returnData['idList'] = $listId;
        return $this->returnMsg(1, 'OK', $returnData);
    }

    // 获取取货地址
    public function getTakeAddress($stId){
        $address = DB::table('school_take')
                    ->leftJoin('config_school', 'school_take.csId', '=', 'config_school.csId')
                    ->where('school_take.csId', $stId)
                    ->first();
        return $this->returnMsg(1, 'OK', $address);
    }

    // 添加订单
    public function addOrder(Request $request){

        $token = $request->token;

        $aaId = $request->aaId;
        $stId = $request->stId;
        $csId = $request->csId;
        $ceId = $request->ceId;
        $ceName = $request->ceName;
        $aoExpressWeight = $request->aoExpressWeight;
        $aoLevel = $request->aoLevel;
        $aoServeTime = $request->aoServeTime;
        $aoPay = $request->aoPay;
        $aoSmsCopy = $request->aoSmsCopy;
        $aoMemo = $request->aoMemo;
        $aoTakeInfo = $request->aoTakeInfo;
        $aoType = $request->aoType;
        $ufId = $request->ufId;
        if (empty($aoType)){
            $aoType = 'express';
        }

        $userInfo = $this->getUserInfoFromToken($token);

        // 处理免单
        if ($ufId){
            $now = date('Y-m-d H:i:s', time());
            $ufInfo = UserFree::where('uId', $userInfo['uCode'])
                        ->where('ufEnable', 1)
                        ->where('ufBeginTime', '<' ,$now)
                        ->where('ufEndTime', '>' ,$now)
                        ->where('ufId', $ufId)
                        ->first();
            if (empty($ufInfo)){
                return $this->returnMsg(0, '订单错误:无免单权利');
            }
        }

        // 开发者测试价格
        if (in_array($userInfo['uThirdId'], $this->developerArray)){
            $aoPay = 0.01;
        }

        $AgencyOrder = new AgencyOrder();
        $orderCode = $AgencyOrder->add($csId, $userInfo['uCode'], $aaId, $stId, $ceId, $ceName, $aoExpressWeight, $aoLevel, $aoServeTime, $aoPay, $aoSmsCopy, $aoMemo, $aoTakeInfo, $aoType);

        ///////////////////////////////////////////////
        $customInfo = array();
        $customInfo['uId'] = $userInfo['uCode'];
        // 创建支付订单
        $payOrderInfo = $this->createPayOrder($aoPay, '校运通', $userInfo['uThirdId'], $request->getClientIp(), $orderCode, json_encode($customInfo));
        $payOrderInfo = json_decode($payOrderInfo, true);

        if ($payOrderInfo['code'] != 1){
            return $this->returnMsg(0, '系统错误，支付失败:'.$payOrderInfo['msg']);
        }

        // 更新支付信息
        $updateData = array();
        $updateData['aoPayParams'] = json_encode($payOrderInfo['data']);
        // 更新免额id
        if($ufId){
            $updateData['ufId'] = $ufId;
        }
        $orderInfo = $AgencyOrder->where('aoCode', $orderCode)->update($updateData);
        ///////////////////////////////////////////////

        return $this->returnMsg(1, 'OK', $payOrderInfo['data']);
    }

    // 支付未完成支付的订单
    public function payOrder(Request $request){

        $token = $request->token;
        $aoId = $request->aoId;

        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyOrder = new AgencyOrder();
        $orderInfo = $AgencyOrder->find($aoId);
        if (empty($orderInfo)){
            return $this->returnMsg(0, '订单不存在');
        }

        return $this->returnMsg(1, 'OK', json_decode($orderInfo->aoPayParams, true));
    }

    // 获取用户订单列表
    public function getUserOrderList($orderType, $token){

        $userInfo = $this->getUserInfoFromToken($token);
        $AgencyOrder = new AgencyOrder();
        $list = $AgencyOrder->getUserList($userInfo['uCode'], $orderType);

        return $this->returnMsg(1, 'OK', $list);
    }

    // 获取快递公司列表
    private function getExpressList($csId){

        $query = DB::table('config_express')
                    ->leftJoin('school_express', 'config_express.ceId', '=', 'school_express.ceId');
        if ($csId != 0){
            $query = $query->where('school_express.csId', $csId);
        }

        $expressNameList = $query->pluck('ceName');
        $expressIdList = $query->pluck('config_express.ceId');
        $returnData = array();
        $returnData['idList'] = $expressIdList;
        $returnData['nameList'] = $expressNameList;

        if (count($expressIdList) == 0){
            $query = DB::table('config_express')->orderBy('ceSort', 'desc');
            $expressNameList = $query->pluck('ceName');
            $expressIdList = $query->pluck('ceId');
            $returnData['idList'] = $expressIdList;
            $returnData['nameList'] = $expressNameList;
        }

        return $returnData;
    }

    // 获取创建订单需要的页面信息
    public function getCreateOrderInfo($token, $aaId=0, $orderType='express', $takeAaId=0){

        $returnData = array();

        if ($aaId == 0){
            // 获取默认收货地址
            $receiveAddressInfo = $this->getDefaultReceiveAddress($token);
            $receiveAddressInfo = $this->handleReturnMsg($receiveAddressInfo);
        }else{
            if ($orderType == 'express' || $orderType == 'takeOut'){
                $receiveAddressInfo = $this->getReceiveAddress($aaId, $token);
                $receiveAddressInfo = $this->handleReturnMsg($receiveAddressInfo);
            }else{
                $receiveAddressInfo = null;
            }
        }

        if ($takeAaId != 0){
            $takeAddressInfo = $this->getReceiveAddress($takeAaId, $token);
            $takeAddressInfo = $this->handleReturnMsg($takeAddressInfo);
            // 取货地址
            $returnData['takeAddressInfo'] = $takeAddressInfo;
        }
        // 收货地址
        $returnData['receiveAddressInfo'] = $receiveAddressInfo;

        $userInfo = $this->getUserInfoFromToken($token, true);
        $csId = $userInfo['addition']['uCustomInfo']['csId'];
        // 获取取货地址列表
        $takeAddressList = $this->getTakeAddressList($csId);
        $takeAddressList = $this->handleReturnMsg($takeAddressList);

        $returnData['takeAddressList'] = $takeAddressList;
        // 设置快递件的大小
        $returnData['packageSize'] = ['小', '中', '大'];
        // 获取快递公司列表
        $expressInfo = $this->getExpressList($csId);
        $returnData['expressInfo'] = $expressInfo;
        // 工作时间id
        $timeNum = $this->getWorkTimeNum();

        $returnData['timeNum'] = $timeNum;
        $timeToastText = '';
        switch ($timeNum)
        {
        case 1:
          $timeToastText = '今日11:30-13:00内配送';
          break;
        case 2:
          $timeToastText = '今日17:30-19:00内配送';
          break;
        case 3:
          $timeToastText = '今日17:30-19:00内配送';
          break;
        case 4:
          $timeToastText = '明日11:30-13:00内配送';
          break;
        case 5:
          $timeToastText = '明日11:30-13:00内配送';
          break;
        }
        $returnData['timeToastText'] = $timeToastText;

        // 判断免费次数
        if ($orderType == 'express'){
            $now = date('Y-m-d H:i:s', time());
            $ufInfo = UserFree::where('uId', $userInfo['uCode'])
                        ->where('ufEnable', 1)
                        ->where('ufBeginTime', '<' ,$now)
                        ->where('ufEndTime', '>' ,$now)
                        ->orderBy('ufEndTime')
                        ->first();
            $returnData['userFree'] = $ufInfo;
        }

        return $this->returnMsg(1, 'OK', $returnData);
    }

    // 处理内部返回json的数据
    private function handleReturnMsg($jsonData){
        $arrayData = json_decode($jsonData, true);
        if ($arrayData['data'] === null){
            return json_decode('{}', true);
        }
        return $arrayData['data'];
    }

    // 获取订单默认金额
    public function getDefaultPay($csId, $stId, $ssId, $size){
//        print_r($size);exit;
        // 获取点对点价格
        $info = DB::table('school_site_take')
                ->where('stId', $stId)
                ->where('ssId', $ssId)
                ->where('aoExpressWeight', $size)
                ->first();

        // 获取校区价格
        if (empty($info)){
            $info = DB::table('school_site_take')
                ->where('stId', 0)
                ->where('ssId', 0)
                ->where('csId', $csId)
                ->where('aoExpressWeight', $size)
                ->first();
        }

        // 获取平台默认价格
        if (empty($info)){
            $info = DB::table('school_site_take')
                ->where('stId', 0)
                ->where('ssId', 0)
                ->where('csId', 0)
                ->where('aoExpressWeight', $size)
                ->first();
        }

        return $this->returnMsg(1, 'OK', $info->sstPrice);
    }

    // 创建支付订单
    private function createPayOrder($pay, $desc, $openid, $clientIp, $customOrderId, $customInfo, $payKey=false){

        $payHost = config('services.extend.payHost');
        $payUrl = $payHost.'/api/pay/unifyOrder';
        // 判断是否自定义key
        if (!$payKey){
            $payKey = config('services.extend.payKey');
        }

        $data['pcKey'] = $payKey;
        $data['pay'] = $pay;
        $data['desc'] = $desc;
        $data['openid'] = $openid;
        $data['clientIp'] = $clientIp;
        $data['customInfo'] = $customInfo;
        $data['customOrderId'] = $customOrderId;

        $Functions = new Functions();
        $data = $Functions->Post($payUrl, $data);

        return $data;
    }

    // 支付回调
    public function payCallback(Request $request){

        //        {
//            "appid": "wxfe2b6f9495c16bc0",
//            "bank_type": "CFT",
//            "cash_fee": "1",
//            "fee_type": "CNY",
//            "is_subscribe": "N",
//            "mch_id": "1233687902",
//            "nonce_str": "Ukrmvh7jXOEQL4PR",
//            "openid": "opSf40A-pyfBG7-AgsrcqHCxAH-U",
//            "out_trade_no": "4A99C505F2914A1A950A494C497D9D14",
//            "result_code": "SUCCESS",
//            "return_code": "SUCCESS",
//            "sign": "20EECE4A238F55DD977C90849FF1F8B3",
//            "time_end": "20180903110023",
//            "total_fee": "1",
//            "trade_type": "JSAPI",
//            "transaction_id": "4200000186201809039798978083",
//            "customInfo": null
//        }

        $customInfo = $request->customInfo;
        $aoCode = $request->out_trade_no;
        $aoPay = $request->total_fee;
        $aoPay = $aoPay * 100;

        // 更改订单状态
        $customInfo = json_decode($customInfo, true);

        if (isset($customInfo['cellphone']) || isset($customInfo['order_sn'])){
            return $this->shopCallback($request);
        }

        $AgencyOrder = new AgencyOrder();
        $aoInfo = $AgencyOrder->payChangeOrderStatus($aoCode, $customInfo['uId']);

        // 处理免单
        if ($aoInfo->ufId > 0){
            $ufInfo = UserFree::find($aoInfo->ufId);
            $ufInfo->ufTimes = $ufInfo->ufTimes - 1;
            if ($ufInfo->ufTimes <= 0){
                $ufInfo->ufEnable = 0;
            }
            $ufInfo->ufUseTime = date('Y-m-d H:i:s', time());
            $ufInfo->save();
        }

        // 判断是否是开发者
        if (!in_array($request->openid, $this->developerArray)){
            // 订单生效后，自动派送
            if ($aoInfo){
                $this->autoSendOrder($aoInfo->aoId);
            }
        }

        ////////////推荐人活动////////////////////////////////
        $this->recommendActivity($customInfo['uId']);
        ////////////推荐人活动////////////////////////////////

        return $this->returnMsg(1, 'OK');
    }

    // 推荐人活动
    public function recommendActivity($uId){

        // 判定是否首单
        $AgencyOrder = new AgencyOrder();
        $orderNum = $AgencyOrder->where('uId', $uId)
                                ->where('aoStatus', '>=', 1)
                                ->where('aoStatus', '<=', 3)
                                ->count();
        if ($orderNum != 1){
            return 1;
        }

        // 获取推荐码
        $Functions = new Functions();
        $authHost = config('services.extend.authHost');
        $commonId = config('services.extend.commonId');
        $getIntroducerUrl = $authHost.'/auth/getIntroducer/'.$commonId.'/'.$uId;
        $introducerInfo = $Functions->Get($getIntroducerUrl);
        $introducerInfo = json_decode($introducerInfo, true);
        if ($introducerInfo['code'] == 0){
            // 无推荐人返回
            return 2;
        }

        $introducer = $introducerInfo['data'];
        $AuthIndexController = new authIndex();
        $AuthIndexController->addShareInfo($introducer, $uId, 2, 'public');
        ///////////////推荐人日常////////////////////////////////////
        $introduceruInfo = $this->getUserInfoFromUid($uId, true);
        $today = date('Y-m-d H:i:s', time());
        $targetDay = date('Y-m-d H:i:s',strtotime('+61 day'));
        DB::table('user_free')->insert([
            'uId' => $uId,
            'csId' => $introduceruInfo['addition']['uCustomInfo']['csId'],
            'ufBeginTime' => $today,
            'ufEndTime' => $targetDay
        ]);

        ///////////////推荐人日常////////////////////////////////////

        ///////////////推荐人活动////////////////////////////////////
        $giftInfo = $AuthIndexController->getActivityStep($introducer, 2);
//        $giftInfo = 0;
        if ($giftInfo == 0){
            // 已送过
        }else if ($giftInfo == 2){
            // 已送完
            $noticeData = array();
            $noticeData['uChannelId'] = config('services.extend.commonId');
            $noticeData['uIds'] = $introducer;
            $noticeData['link'] = '';
            $noticeData['first'] = '非常抱歉！活动名额已满';
            $noticeData['activityName'] = '期末分享活动';
            $noticeData['activityResult'] = '成功转化'.$giftInfo['stepNum'].'个用户下单';
            $noticeData['activityTime'] = date('Y-m-d H:i:s', time());
            $noticeData['activitySponsor'] = '成都思先行科技';
            $noticeData['remark'] = '非常感谢参与校运通活动，下次我们会准备更多奖品，记得早点来哦！';
            $AuthIndexController->extendRequest('/auth/activityResultNotice', $noticeData);
        }else{
            if ($giftInfo['isSend'] == 1){
                // 送
                DB::table('user_free')->insert([
                    'uId' => $uId,
                    'ufTimes' => 300,
                    'csId' => $introduceruInfo['addition']['uCustomInfo']['csId'],
                    'ufBeginTime' => '2018-03-01',
                    'ufEndTime' => '2018-08-01'
                ]);

                $noticeData = array();
                $noticeData['uChannelId'] = config('services.extend.commonId');
                $noticeData['uIds'] = $introducer;
                $noticeData['link'] = '';
                $noticeData['first'] = '恭喜你成为下学期校运通特等VIP';
                $noticeData['activityName'] = '期末分享活动';
                $noticeData['activityResult'] = '成功转化'.$giftInfo['stepNum'].'个用户下单';
                $noticeData['activityTime'] = '2019-03-01到2019-09-01';
                $noticeData['activitySponsor'] = '成都思先行科技';
                $noticeData['remark'] = '非常感谢参与校运通活动!';
                $AuthIndexController->extendRequest('/auth/activityResultNotice', $noticeData);
            }else{
                // 未达标
                $noticeData = array();
                $noticeData['uChannelId'] = config('services.extend.commonId');
                $noticeData['uIds'] = $introducer;
                $noticeData['link'] = '';
                $noticeData['first'] = '再接再厉！';
                $noticeData['activityName'] = '期末分享活动';
                $noticeData['activityResult'] = '已成功转化'.$giftInfo['stepNum'].'个用户下单';
                $noticeData['activityTime'] = date('Y-m-d H:i:s', time());
                $noticeData['activitySponsor'] = '成都思先行科技';
                $noticeData['remark'] = '非常感谢参与校运通活动!';
                $AuthIndexController->extendRequest('/auth/activityResultNotice', $noticeData);
            }
        }
        ///////////////推荐人活动////////////////////////////////////
        return 'OK';
    }

    // 获取订单详情
    public function getOrderInfo($token, $aoId){

        $userInfo = $this->getUserInfoFromToken($token);

        $AgencyOrder = new AgencyOrder();
        $info = $AgencyOrder->getInfo($aoId);
        if (isset($_GET['from']) && $_GET['from'] == 'shop'){
            $info = $AgencyOrder->getInfoFromAoCode($aoId);
        }
        $temp = $AgencyOrder->doTimeFlag([$info]);
        $info = $temp[0];

        if ($info->kId){
            $Knight = new Knight();
            $knightInfo = $Knight::find($info->kId);
            $knightUserInfo = $this->getUserInfoFromUid($knightInfo->uId, true);
            $info['knight'] = $knightUserInfo['addition'];
        }

        return $this->returnMsg(1, 'OK', $info);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 自动派单
    public function autoSendOrder($aoId){

        $aoInfo = DB::table('agency_order')
                    ->select(['agency_order.*', 'ssId'])
                    ->leftJoin('agency_address', 'agency_order.aaId', '=', 'agency_address.aaId')
                    ->where('aoId', $aoId)
                    ->first();

        $today = date("Y-m-d");
        $nowKsid = $this->getNowKsid();

        $KnightWork = new KnightWork();

        // 查询所有可接单的骑士，然后根据任务饱和度优先派发订单
        $waitKnightList = array();

        for($i=0; $i<4; $i++){
            $level = 4 - $i;

            // 查询条件： 查询状态有效骑士，订单所在校区，开启当前时间派送或开启自动派单，
            // 排序：等级从高到底，优先派给空闲骑士(或当未完成单数量少的骑士)， 然后系统派单给距离上次派单时间最远的骑士
            $sql = "SELECT DISTINCT
                        k.kId, k.kIsWorking, IFNULL(kw.kwId, 0) AS kwId, k.klId,
                        IFNULL(kw.kwAssignNum, 0) AS kwAssignNum,
                        IFNULL(kw.kwLastAssignTime, '2018-01-01') AS kwLastAssignTime
                    FROM
                        knight AS k
                    LEFT JOIN knight_hour AS kh ON k.kId = kh.kId
                    LEFT JOIN knight_work AS kw ON k.kId = kw.kId
                    AND kw.kwDay = ?
                    WHERE
                        k.kStatus = 1
                    AND k.csId = ?
                    AND k.klId = ?
                    AND (kh.ksId = ? OR k.kAutoTask = 1)
                    ORDER BY k.kIsWorking ";

            $knightList = DB::select($sql, [$today, $aoInfo->csId, $level, $nowKsid]);
            if (count($knightList) > 0){
                // 高等级骑士无法指定地点
                if ($level >= 3){
                    // 同工作饱和度，选择上次派单时间最远骑士
                    $fitKnightInfo = $this->sameSaturabilityChooseAssignTime($knightList);
                    array_push($waitKnightList, $fitKnightInfo);
//                    $this->sendOrderToKnight($kId, $aoId);
//                    $KnightWork->addAutoInfo($kId);
//                    return $kId;
                }else{
                    // 可派送骑士列表
                    $canSendKnightList = array();
                    // 判断指定送达地点
                    foreach($knightList as $knightInfo){
                        $askAddressList = DB::table('knight_ask_address')->where('kId', $knightInfo->kId)->pluck('ssId');
                        $askAddressList = json_decode(json_encode($askAddressList), true);
                        // 无指定地点，即都可以派送
                        if (empty($askAddressList)){
                            array_push($canSendKnightList, $knightInfo);
                        }else{
                            // 判断送达地点是否在指定地点内
                            if (in_array($aoInfo->ssId, $askAddressList)){
                                array_push($canSendKnightList, $knightInfo);
                            }
                        }
                    }

                    if (count($canSendKnightList) > 0){
                        // 同工作饱和度，选择上次派单时间最远骑士
                        $fitKnightInfo = $this->sameSaturabilityChooseAssignTime($canSendKnightList);
                        array_push($waitKnightList, $fitKnightInfo);
//                        $this->sendOrderToKnight($kId, $aoId);
//                        $KnightWork->addAutoInfo($kId);
//                        return $kId;
                    }
                }
            }
        }

        // 先进行工作饱和度排序，饱和度低的排最前
        $waitKnightList = $this->sortKnightListByWorking($waitKnightList);
        // 进行上次派单时间排序，距离上次派单时间越远，越优先
        $bestKnightInfo = $this->sameSaturabilityChooseAssignTime($waitKnightList);

        if (!empty($bestKnightInfo)){
            $this->sendOrderToKnight($bestKnightInfo->kId, $aoId);
            $KnightWork->addAutoInfo($bestKnightInfo->kId);
            return $bestKnightInfo->kId;
        }

        // 等待超时，将发送订单到校园经理人
        $now = strtotime('now');
        $orderTime = strtotime($aoInfo->createTime);
        $dueTime = 60 * 15; // 过期时间
        if (($now - $orderTime) > $dueTime){
            $schoolManagerInfo = DB::table('school_manager')->where('csId', $aoInfo->csId)->first();
            if (!empty($schoolManagerInfo)){
                $this->sendOrderToKnight($schoolManagerInfo->kId, $aoId);
                $KnightWork->addAutoInfo($schoolManagerInfo->kId);
                return $schoolManagerInfo->kId;
            }
        }

        return false;
    }

    // 同工作饱和度，选择上次派单时间最远骑士
    private function sameSaturabilityChooseAssignTime($knightList){
//        print_r($knightList);exit;
        $now = strtotime('now');
        // 时间差
        $difference = 0;
        $kIsWorking = -1;
        $fitKnightInfo = array();

        foreach($knightList as $knightInfo){
            $kwLastAssignTime = strtotime($knightInfo->kwLastAssignTime);
            $currentDifference = $now - $kwLastAssignTime;
            // 第一个骑士
            if ($kIsWorking == -1){
                $kIsWorking = $knightInfo->kIsWorking;
                $fitKnightInfo = $knightInfo;
                $difference = $currentDifference;
            }
            // 判断饱和度是否改变
            if ($knightInfo->kIsWorking != $kIsWorking){
//                return $kId;
                return $fitKnightInfo;
            }

            // 判断时间差是否比上一个大
            if ($currentDifference > $difference){
                $fitKnightInfo = $knightInfo;
                $difference = $currentDifference;
            }
        }

        return $fitKnightInfo;
    }

    // 筛选饱和度最低的
    private function sortKnightListByWorking($knightList){

        $workingNum = array();
        $klIds = array();
        foreach($knightList as $knightInfo){
            array_push($workingNum, $knightInfo->kIsWorking);
            array_push($klIds, $knightInfo->klId);
        }

        array_multisort($workingNum, SORT_ASC, $klIds, SORT_ASC, $knightList);
        return $knightList;
    }

    // 派单给骑士
    private function sendOrderToKnight($kId, $aoId){
        $AgencyOrder = new AgencyOrder();
        $aoInfo = $AgencyOrder->knightChangeOrderStatus($kId, $aoId, 1);

        $Knight = new Knight();
        $kInfo = $Knight->where('kId', $kId)->first();
        // 通知骑士接单
        $requestPath = '/auth/acceptOrderNotice';
        $data = array();
        $data['uChannelId'] = config('services.extend.commonId');
        $data['uIds'] = $kInfo->uId;
        $data['link'] = 'pages/index/index?page=detail&name=aoId&id='.$aoInfo->aoId;
        $data['first'] = '伟大的骑士，您有一个新的订单！';
        $data['orderNo'] = $aoInfo->aoCode;
        $data['money'] = $aoInfo->aoPay;
        $data['taskType'] = '代取快递';
        $data['remark'] = '点击可查看详情';
        $this->extendRequest($requestPath, $data);
    }

    // 获取当前时间所属时间段ID
    public function getNowKsid(){

        $today = date("Y-m-d");
        $now = strtotime(date('Y-m-d H:i:s', time()));

        $scheduleList = DB::table('knight_schedule')->get();
        foreach($scheduleList as $scheduleInfo){
            $ksTimeBucket = str_replace(" ", "", $scheduleInfo->ksTimeBucket);
            $beginTime = strtotime($today.' '.explode("-",$ksTimeBucket)[0].':00');
            $endTime = strtotime($today.' '.explode("-",$ksTimeBucket)[1].':00');
            if ($beginTime <= $now && $now <= $endTime){
                return $scheduleInfo->ksId;
            }
        }
        return 0;
    }

    // 自动派单任务
    public function autoSendOrderTask(){
        $schoolIdList = DB::table('config_school')->pluck('csId');
        $AgencyOrder = new AgencyOrder();
        foreach($schoolIdList as $csId){
            $orderList = $AgencyOrder->getTaskList($csId);
            foreach($orderList as $orderInfo){
                $this->autoSendOrder($orderInfo['aoId']);
            }
        }

        echo 'OK';
    }

    ///////////////////////////////////////////////////////////////////////

    // 通过取货地点获取快递公司列表
    public function getTakeExpress($stId){

        $nameList = DB::table('school_take_express')
                        ->leftJoin('config_express', 'school_take_express.ceId', '=', 'config_express.ceId')
                        ->where('stId', $stId)
                        ->where('ceEnable', 1)
                        ->orderBy('ceSort', 'DESC')
                        ->pluck('config_express.ceName');
        $idList = DB::table('school_take_express')
                    ->leftJoin('config_express', 'school_take_express.ceId', '=', 'config_express.ceId')
                    ->where('stId', $stId)
                    ->where('ceEnable', 1)
                    ->orderBy('ceSort', 'DESC')
                    ->pluck('school_take_express.ceId');
        $returnData = array();
        $returnData['nameList'] = $nameList;
        $returnData['idList'] = $idList;
        return $this->returnMsg(1, 'OK', $returnData);
    }

    // 请求扩展数据
    private function extendRequest($requestPath, $requestData=null){
        $Functions = new Functions();
        $authHost = config('services.extend.authHost');
        $requestUrl = $authHost.$requestPath;
        if (empty($requestData)){
            $data = $Functions->Get($requestUrl);
        }else{
            $data = $Functions->Post($requestUrl, $requestData);
        }
        return $data;
    }

    // 获取工作时间段
    private function getWorkTimeNum(){
        $nowTime = (int)date('His', time());

        if (0 <= $nowTime && $nowTime <= 110000){
            return 1;
            return $this->returnMsg(1, '预定当天中午', 1); // 预定当天中午
        }
        if (110000 < $nowTime && $nowTime <= 130000){
            return 2;
            return $this->returnMsg(1, '中午，加急服务', 2); // 中午，加急服务
        }
        if (130000 < $nowTime && $nowTime <= 170000){
            return 3;
            return $this->returnMsg(1, '预定当天下午', 3); // 预定当天下午
        }
        if (170000 < $nowTime && $nowTime <= 190000){
            return 4;
            return $this->returnMsg(1, '下午，加急服务', 4); // 下午，加急服务
        }
        if (190000 < $nowTime && $nowTime < 240000){
            return 5;
            return $this->returnMsg(1, '预定第二日中午', 5); // 预定第二日中午
        }
    }

    // 获取外卖跑腿价格配置
    public function getTakeOutPriceConfig($csName){
        $schoolInfo = DB::table('config_school')->where('csName', $csName)->first();
        if (empty($schoolInfo)){
            return $this->returnMsg(0, '无此校区');
        }
        $data = $this->getPriceConfig($schoolInfo->csId, 'takeOut');
        $dataArray = json_decode($data, true);
        $returnData = array();
        foreach($dataArray['data'] as $priceInfo){
            $returnData[$priceInfo['cpProperty']] = $priceInfo['cpPrice'];
        }
        return $this->returnMsg(1, 'OK', $returnData);
    }

    // 获取价格配置
    public function getPriceConfig($csId, $type){

        $defaultPriceList = DB::table('config_price')
                        ->select(['cpId', 'csId', 'cpType', 'cpProperty', 'cpPrice'])
                        ->where('cpType', $type)
                        ->where('cpEnable', 1)
                        ->where('csId', 0)
                        ->get();

        $priceList = DB::table('config_price')
                        ->select(['cpId', 'csId', 'cpType', 'cpProperty', 'cpPrice'])
                        ->where('cpType', $type)
                        ->where('cpEnable', 1)
                        ->where('csId', $csId)
                        ->get();

        $returnList = array();
        foreach($defaultPriceList as $defaultInfo){
            $isHave = false;
            foreach($priceList as $info){
                if ($defaultInfo->cpProperty == $info->cpProperty){
                    $isHave = true;
                    array_push($returnList, $info);
                    break;
                }
            }
            if (!$isHave){
                array_push($returnList, $defaultInfo);
            }
        }

        return $this->returnMsg(1, 'OK', $returnList);
    }

    // 接受转单
    public function acceptTurnOrder(Request $request){

        $token = $request->token;
        $userInfo = $this->getUserInfoFromToken($token);
        $aoId = $request->aoId;
        $kUid = $userInfo['uCode'];

        $agencyOrder = new AgencyOrder();
        $res = $agencyOrder->turnOrder($aoId, $kUid);

        return $this->returnMsg($res['code'], $res['msg']);
    }

    ////////////商城///////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 获取商城手机加密字符串
    public function getMobileToken($token){

        $userInfo = $this->getUserInfoFromToken($token, true);
        $school = 0;
        if (isset($userInfo['addition']['uSchool'])){
            if (!empty($userInfo['addition']['uSchool'])){
                $school = $userInfo['addition']['uSchool'];
            }
        }
        $token = $this->getToken($userInfo['addition']['uMobile'], base64_encode($school), $userInfo['uThirdId']);

        return $this->returnMsg(1, 'OK', $token);
    }

    /**
     * 加密函数
     * @param $txt
     * @param string $key
     * @return string
     */
    private function jiami($txt,$key='sxxapiloginmima')
    {
        $txt = $txt.$key;
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";
        $nh = rand(0,64);
        $ch = $chars[$nh];
        $mdKey = md5($key.$ch);
        $mdKey = substr($mdKey,$nh%8, $nh%8+7);
        $txt = base64_encode($txt);
        $tmp = '';
        $i=0;$j=0;$k = 0;
        for ($i=0; $i<strlen($txt); $i++) {
            $k = $k == strlen($mdKey) ? 0 : $k;
            $j = ($nh+strpos($chars,$txt[$i])+ord($mdKey[$k++]))%64;
            $tmp .= $chars[$j];
        }
        return urlencode(base64_encode($ch.$tmp));
    }

    /**
     * 解密函数
     * @param $txt
     * @param string $key
     * @return string
     */
    private function jiemi($txt,$key='sxxapiloginmima')
    {
        $txt = base64_decode(urldecode($txt));
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+";
        $ch = $txt[0];
        $nh = strpos($chars,$ch);
        $mdKey = md5($key.$ch);
        $mdKey = substr($mdKey,$nh%8, $nh%8+7);
        $txt = substr($txt,1);
        $tmp = '';
        $i=0;$j=0; $k = 0;
        for ($i=0; $i<strlen($txt); $i++) {
            $k = $k == strlen($mdKey) ? 0 : $k;
            $j = strpos($chars,$txt[$i])-$nh - ord($mdKey[$k++]);
            while ($j<0) $j+=64;
            $tmp .= $chars[$j];
        }
        return trim(base64_decode($tmp),$key);
    }

    private function getToken($phone, $school, $openid){

        $token = $phone . ',' . (time() + 180) . ',' . $school. ',' . $openid;
        return $this->jiami($token);
    }

    // 获取商品订单信息
    public function getGoodsOrderInfo($orderCode){

        $data = $this->getGoodsOrderInfoArray($orderCode);
        return $this->returnMsg(1, $data['msg'], $data['data']);
    }

    private function getGoodsOrderInfoArray($orderCode){
        $Functions = new Functions();
        $data = $Functions->Get('http://shop.sbedian.com/api/order/detail/'.$orderCode);
        $data = json_decode($data, true);

        if ($data['code'] != 0){
            echo $this->returnMsg(0, $data['msg']);
            exit;
        }
        return $data;
    }

    // 获取商品订单支付信息
    public function getGoodsPayInfo($orderCode, Request $request){
        return $this->returnMsg(0, '下学期再来哦~');
        $Functions = new Functions();

        $data = $Functions->Get('http://shop.sbedian.com/api/order/detail/'.$orderCode);
        $bk = $data;
        $data = json_decode($data, true);
        if (empty($data)){
            Log::error('http://shop.sbedian.com/api/order/detail/'.$orderCode);
            Log::error($bk);
            return $this->returnMsg(0, '获取订单信息失败');
        }

        if ($data['code'] != 0){
            return $this->returnMsg(0, $data['msg']);
        }
        $data = $data['data'];
        if ($request->token){
            $userInfo = $this->getUserInfoFromToken($request->token, true);
        }else{
            $userInfo = $this->getUserInfoFromUserMobile($data['cellphone']);
        }
        // $userInfo = $this->getUserInfoFromUserMobile($data['cellphone']);

        $clientIp = $request->getClientIp();
//        $data['price_pay'] = 0.01;
        $payOrderInfo = $this->createPayOrder($data['price_pay'], $data['goods_name'], $userInfo['uThirdId'], $clientIp, $orderCode, json_encode($data));

        $payOrderInfo = json_decode($payOrderInfo, true);

        if ($payOrderInfo['code'] != 1){
            return $this->returnMsg(0, '系统错误，支付失败:'.$payOrderInfo['msg']);
        }
        $payOrderInfo['data']['shop_name'] = $data['shop_name'];
        return $this->returnMsg(1, 'OK', $payOrderInfo['data']);

        //createPayOrder($pay, $desc, $openid, $clientIp, $customOrderId, $customInfo)
    }

    // 店铺回调
    public function shopCallback(Request $request){

//        {
//            "appid": "wxfe2b6f9495c16bc0",
//            "bank_type": "CFT",
//            "cash_fee": "1",
//            "fee_type": "CNY",
//            "is_subscribe": "N",
//            "mch_id": "1233687902",
//            "nonce_str": "Ukrmvh7jXOEQL4PR",
//            "openid": "opSf40A-pyfBG7-AgsrcqHCxAH-U",
//            "out_trade_no": "4A99C505F2914A1A950A494C497D9D14",
//            "result_code": "SUCCESS",
//            "return_code": "SUCCESS",
//            "sign": "20EECE4A238F55DD977C90849FF1F8B3",
//            "time_end": "20180903110023",
//            "total_fee": "1",
//            "trade_type": "JSAPI",
//            "transaction_id": "4200000186201809039798978083",
//            "customInfo": null
//        }


        $customInfo = $request->customInfo;
        $out_trade_no = $request->out_trade_no;

        $AgencyOrder = new AgencyOrder();
        $aoCheckInfo = $AgencyOrder->where('aoCode', $out_trade_no)->first();
        if ($aoCheckInfo){
            if ($aoCheckInfo->aoStatus != -2){
                Log::error('订单号：【' . $out_trade_no . '】通知重复');
                return $this->returnMsg(1, 'OK', '通知重复');
            }
        }


        $customInfo = json_decode($customInfo, true);
        $userInfo = $this->getUserInfoFromOpenid($request->openid, true);
        // $userInfo = array();
        // if ($customInfo['cellphone']){
        //     $userInfo = $this->getUserInfoFromUid($aoCheckInfo->uId, true);
        // }else{
        //     $userInfo = $this->getUserInfoFromUserMobile($customInfo['cellphone']);
        // }

        $school = 0;
        if (isset($userInfo['addition']['uSchool'])){
            if (!empty($userInfo['addition']['uSchool'])){
                $school = $userInfo['addition']['uSchool'];
            }
        }
        $tokenStr = $this->getToken($customInfo['cellphone'], base64_encode($school), $request->openid);
//        print_r($userInfo);exit;
        $orderInfo = $this->getGoodsOrderInfoArray($out_trade_no);
        $orderInfo = $orderInfo['data'];


        // $aoInfo = $AgencyOrder->where('aoCode', $orderInfo['order_sn'])->first();
        // if (!empty($aoInfo)){
        //     return $this->returnMsg(1, 'OK');
        // }

        $aoPay = $request->total_fee / 100;
        $aoType = 'shop';
        $aoLevel = 0; // 临时
        //$aoTakeInfo = $orderInfo['goods_name'].'|'.$orderInfo['address'];
        $aoTakeInfo = json_encode($orderInfo);
        $aoMemo = $orderInfo['remark'];
        $aoCode = $AgencyOrder->add($userInfo['addition']['uCustomInfo']['csId'], $userInfo['uCode'], null, null, null, null, null, $aoLevel, null, $aoPay, null, $aoMemo, $aoTakeInfo, $aoType);
        $aoInfo = $AgencyOrder->where('aoCode', $aoCode)->first();
        $aoInfo->aoCode = $orderInfo['order_sn'];
        $aoInfo->aoStatus = 0;
        $aoInfo->save();

        $noticeResult = Curl::to('http://shop.sbedian.com/notify/wxpayWaimai2')
            ->withData(['token' => $tokenStr, 'out_trade_no'=> $out_trade_no])
            ->get();

        $url = "http://shop.sbedian.com/notify/wxpayWaimai2?token={$tokenStr}&out_trade_no={$out_trade_no}";

        // 1：商品金额结算给骑士；0 商品金额结算给商家
        $isVirtual = $customInfo['is_virtual'];
        if (!$isVirtual){
            // 通知商家
            $noticeData = array();
            $noticeData['uChannelId'] = config('services.extend.commonId');
            $noticeData['sjCode'] = $customInfo['shop_code'];
            $noticeData['link'] = 'http://shop.sbedian.com/shop/todayOrderMobile/'.$customInfo['order_sn'];
            $noticeData['orderTitle'] = '您有一个新订单';
            $noticeData['orderTime'] = date('Y-m-d H:i:s', time());
            $noticeData['orderName'] = $customInfo['goods_name'];
            $noticeData['orderPay'] = $customInfo['price_pay'];
            $noticeData['orderMobile'] = $customInfo['cellphone'];
            $noticeData['orderAddress'] = $customInfo['address'];
            $noticeData['orderMemo'] = $customInfo['remark'];

            $authHost = config('services.extend.authHost');
            $wxNoticeUrl = "{$authHost}/auth/orderSendNotice";

            $wxNoticeResult = Curl::to($wxNoticeUrl)->withData($noticeData)->post();
        }

        return $this->returnMsg(1, 'OK:'.$url, $noticeResult);
    }

    // 获取订单状态
    public function getOrderStatue($aoCode){

        $AgencyOrder = new AgencyOrder();
        $aoInfo = $AgencyOrder->where('aoCode', $aoCode)->first();

        return $this->returnMsg(1, 'OK', $aoInfo->aoStatus);
    }

    // 向商家付款
    public function payToMerchant(Request $request){

        $payMoney = $request->payMoney;
        $desc = $request->desc;
        $name = $request->name;
        $merchantCode = $request->merchantCode;
        $orderId = $request->orderId;

        $pcKey = 'IBB4oPNabTi674zn';
        $uChannelId = config('services.extend.commonId');
        $ip = $request->getClientIp();

        if (!is_numeric($payMoney)){
            return $this->returnMsg(0, '支付金额格式不正确');
        }

        // 获取openid
        $authHost = config('services.extend.authHost');
        $getOpenidUrl = $authHost."/auth/getPayGroupOpenId/{$merchantCode}/1";
        $getResult = Curl::to($getOpenidUrl)->get();
        $getResult = json_decode($getResult, true);

        if ($getResult['code'] == 0){
            return $this->returnMsg(0, $getResult['msg']);
        }
        $openid = $getResult['data'];

        $payHost = config('services.extend.payHost');
        $payUrl = $payHost.'/api/pay/companyPay';

        $postData = array();
        $postData['pcKey'] = $pcKey;
        $postData['clientIp'] = $ip;
        $postData['pay'] = $payMoney;
        $postData['desc'] = $desc;
        $postData['openid'] = $openid;
        $postData['customOrderId'] = $orderId;
        $postData['unionid'] = '';
        $postData['uChannelId'] = $uChannelId;
        $postData['cardName'] = $name;

        $response = Curl::to($payUrl)->withData($postData)->post();

        return $response;
    }

    ////////////商城///////////////////////////////////////////////////////////////////////////////////////////////////////////

    public function getYesterdayExpressList(Request $request){

        $isShow = $request->isShow;
        $list = "";
        $today = date("Y-m-d");
        $yesterday = date("Y-m-d",strtotime("-1 day"));
        if ($isShow == 'show'){
            $list = DB::select("SELECT als.shop_name, CONCAT('\'', ao.order_sn) AS order_sn, au.user_name, au.phone, ao.remark, pg.pgDescribe, COUNT(pu.pId) AS picNums, ao.price_pay,ao.create_at, pg.pgId
            FROM db_yiadmin_shop.all_order AS ao LEFT JOIN xyt_new.picture_group AS pg ON CONCAT(ao.order_sn, '_user') = pg.pgBelongId
            LEFT JOIN db_yiadmin_shop.all_shop AS als ON ao.sid = als.id
            LEFT JOIN db_yiadmin_shop.all_user AS au ON ao.uid = au.id
            LEFT JOIN xyt_new.picture_url AS pu ON pg.pgId = pu.pgId
            WHERE (ao.sid = 'D823733E-E27E-9A09-F8E1-2B06BA1FA1BD' OR ao.remark != null) AND ao.create_at > '{$yesterday}' AND au.user_name != '高耸' AND au.user_name != '易先生' AND ao.`status` = 20
            GROUP BY ao.order_sn, als.shop_name, au.user_name, au.phone, ao.remark, pg.pgDescribe, ao.price_pay, ao.price_pay,ao.create_at, pg.pgId
            ORDER BY ao.create_at");
        }else{
            $list = DB::select("SELECT als.shop_name, CONCAT('\'', ao.order_sn) AS order_sn, au.user_name, CONCAT(left(au.phone, 3),'****', right(au.phone, 4)) AS phone, ao.remark, pg.pgDescribe, COUNT(pu.pId) AS picNums, ao.price_pay,ao.create_at, pg.pgId
            FROM db_yiadmin_shop.all_order AS ao LEFT JOIN xyt_new.picture_group AS pg ON CONCAT(ao.order_sn, '_user') = pg.pgBelongId
            LEFT JOIN db_yiadmin_shop.all_shop AS als ON ao.sid = als.id
            LEFT JOIN db_yiadmin_shop.all_user AS au ON ao.uid = au.id
            LEFT JOIN xyt_new.picture_url AS pu ON pg.pgId = pu.pgId
            WHERE (ao.sid = 'D823733E-E27E-9A09-F8E1-2B06BA1FA1BD' OR ao.remark != null) AND ao.create_at > '{$yesterday}' AND au.user_name != '高耸' AND au.user_name != '易先生' AND ao.`status` = 20
            GROUP BY ao.order_sn, als.shop_name, au.user_name, au.phone, ao.remark, pg.pgDescribe, ao.price_pay, ao.price_pay,ao.create_at, pg.pgId
            ORDER BY ao.create_at");
        }


        // print_r($list);exit;
        for ($i=0;$i<count($list);$i++){
            $picList = DB::table('picture_url')->where('pgId', $list[$i]->pgId)->get();
            $list[$i]->picList = $picList;
        }

        return view('order.expressList', array('listData'=>$list));
    }
}
